#include <stdlib.h>
#include <conio.h>
#define Get(C) for (C, i = n[T]; j = X + i % 4, k = Y + i / 4 % 4, i; i >>= 4)
int W = 10, H = 25, S, i, j, k, c, d = 0, X = 0, Y = 0, T = 0, *m, n[] = {
	51264, 12816, 21520, 21520, 25872, 34113, 21537, 38208, 25921, 38481,
	38484, 38209, 25922, 43345, 34388, 38160, 25920, 38177, 42580, 38993};
int move(int* v, int l) {
	Get (*v += l)(j < 0 || j >= W || k >= H || m[k * W + j]) && (c = 0);
	return c ? 1 : (*v -= l, v == &Y && (c = -1));
}
int main() {
	for (srand(m = calloc(S = W * H, 4)); c - 27; _sleep(50), system("cls")) {
		Get(c = _kbhit() ? _getch() & 95 : 1) m[k * W + j] = 0;
		c ^ 65 || move(&X, -1), c ^ 68 || move(&X, 1), c ^ 83 || move(&Y, 1);
		c ^ 87 || (i = T < 8 ? 1 : 3, move(&T, T & i ^ i ? 1 : -i));
		Get(++d - 10 || (d = 0, c = 1, move(&Y, 1))) m[k * W + j] = 1;
		if (c == -1 && !(Y || (c = 27), T = rand() % 20, Y = X = 0))
			for (j = W, i = S - 1; j -= m[i], i; i-- % W || (j = W))
				for (j || (k = i += W); !j && (--k >= W); m[k] = m[k - W]);
		for (; i < S; ++i % W || _cputs("|\n"))_cputs(m[i] ? "[]" : "  ");
	}
}

/*
22行俄罗斯方块, 1110字符, 实现了简单的功能;
AD移动, S下坠, W旋转, 某一行填满方块则消行, 当方块堆到顶层或按下Esc键时游戏结束;
可自定义地图尺寸(W, H)
在30行的版本上加以改进, 优化部分逻辑, 代码量大幅减少
此处使用gcc编译通过, vs需要屏蔽4996号错误, 加上下面一行代码
#pragma warning(disable:4996)

2021.2.6
	调整代码
2020.11.13
	优化代码
2020.10.2
	补充说明, 优化代码, 行数-2
2020.9.19
	*把2行超过80字符的段落压缩了一下
	*解决了移动与下落会冲突的问题
2020.9.13
	上传
*/
